package com.loongtech.bi.manager.game;

import com.loongtech.bi.action.PageHelper;
import com.loongtech.bi.entity.game.EntityActiveRoleNumByVipAndLevel;
import com.loongtech.bi.entity.game.EntityRoleActivityJoinNum;
import com.loongtech.bi.entity.game.EntityRoleActivityJoinRate;
import com.loongtech.bi.manager.system.BiPlatformManager;
import com.loongtech.bi.manager.system.GameParamConfigManager;
import com.loongtech.bi.support.CommonGameParam;
import com.loongtech.bi.support.chart.ChartData1;
import com.loongtech.bi.support.chart.ChartFlow;
import com.loongtech.bi.support.chart.ChartSelect;
import com.loongtech.core.jpa.manager.ManagerQueryCacheBase;
import com.loongtech.core.util.Time;
import org.datanucleus.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 游戏内分析-活动分析manager
 * 
 * @author marin
 * @date 2015-09-15
 */
@Service
public class ActivityGameManager extends ManagerQueryCacheBase<Object> {
	private static final long serialVersionUID = 1L;
	
	@Autowired
	private RoleActivityJoinNumManager roleActivityJoinNumManager;
    @Autowired
    private RoleActivityJoinRateManager roleActivityJoinRateManager;
    @Autowired
    private ActiveRoleNumByVipandLevelManager activeRoleNumByVipandLevelManager;

    public List<ActivityUserJoinRateData> getRoleAcitvityJoinRateDatas(Date dateStart, Date dateEnd, String queryPlatform, String queryChannel, String queryServer, List<Integer> queryVipLevels, String activityType, List<String> activities) {
        if (activities == null || activities.size() <= 0) {
            return null;
        }

        List<ActivityUserJoinRateData> result = new ArrayList<>();

        List<EntityRoleActivityJoinRate> ll = null;
        List<EntityActiveRoleNumByVipAndLevel> list = null;
        if (queryVipLevels == null || queryVipLevels.size() <= 0) {
            ll = roleActivityJoinRateManager.getDatas(dateStart, dateEnd, queryPlatform, queryChannel, queryServer, activityType, activities);
            list = activeRoleNumByVipandLevelManager.getDatas(dateStart, dateEnd, queryPlatform, queryChannel, queryServer);
        } else {
            ll = roleActivityJoinRateManager.getDatasByVipLevel(dateStart, dateEnd, queryPlatform, queryChannel, queryServer, activityType, activities, queryVipLevels);
            list = activeRoleNumByVipandLevelManager.getDatasByVipLevel(dateStart, dateEnd, queryPlatform, queryChannel, queryServer, queryVipLevels);
        }

        if (ll != null && ll.size() > 0) {
            Map<String, ActivityUserJoinRateData> tmp = new LinkedHashMap<>();
            for (EntityRoleActivityJoinRate e : ll) {
                String key = Time.getDateStr(e.getDay()) + "-" + e.getActivitytype() + "-" + e.getActivityid();

                ActivityUserJoinRateData erajr = tmp.get(key);
                if (erajr == null) {
                    erajr = new ActivityUserJoinRateData();

                    erajr.setDay(Time.getDateStr(e.getDay()));
                    erajr.setPlatformId(e.getPlatformid());
                    erajr.setChannelId(e.getChannelid());
                    erajr.setServerId(e.getServerid());
                    erajr.setActivitytype(e.getActivitytype());
                    erajr.setActivityid(e.getActivityid());

                    tmp.put(key, erajr);
                }
                erajr.setUserNum(erajr.getUserNum() + e.getRolenum());
                erajr.setJoinNum(erajr.getJoinNum() + e.getJoinnum());
            }

            Map<String, Map<Integer, Integer>> activeLevelNumTemp = new LinkedHashMap<>();  // datestr=level=rolenum  某天大于等于level等级的角色数
            if (list != null && list.size() > 0) {
                for (EntityActiveRoleNumByVipAndLevel e : list) {
                    String date = Time.getDateStr(e.getDay());
                    int level = e.getLevel();
                    int num = e.getRolenum();

                    Map<Integer, Integer> tt = activeLevelNumTemp.get(date);
                    if (tt == null) {
                        tt = new LinkedHashMap<>();
                        activeLevelNumTemp.put(date, tt);
                        tt.put(level, num);
                    } else {
                        for (Map.Entry<Integer, Integer> entry : tt.entrySet()) {
                            if (entry.getKey() <= level) {
                                tt.put(entry.getKey(), entry.getValue() + num);
                            }
                        }
                        if (tt.get(level) == null) {
                            tt.put(level, num);
                        }
                    }
                }
            }

            for (Map.Entry<String, ActivityUserJoinRateData> entry : tmp.entrySet()) {
                ActivityUserJoinRateData erajr = entry.getValue();

                int okusernum = 0;
                if (activeLevelNumTemp != null && activeLevelNumTemp.size() > 0) {
                    Map<Integer, Integer> tll = activeLevelNumTemp.get(erajr.getDay());
                    if (tll != null && tll.size() > 0) {
                        String levelStr = GameParamConfigManager.getItemsRevise(CommonGameParam.ACTIVITY_OPEN_LEVEL).get(erajr.getActivityid());
                        if (!StringUtils.isEmpty(levelStr)) {
                            okusernum = tll.get(Integer.parseInt(levelStr)) == null ? 0 : tll.get(Integer.parseInt(levelStr));
                        }
                    }
                }
                erajr.setOkUserNum(okusernum);

                erajr.setJoinProUserNum(erajr.getUserNum() == 0 ? 0 : PageHelper.floatKeepOneNumber(erajr.getJoinNum() * 1.0 / erajr.getUserNum()));
                erajr.setUserJoinRate(erajr.getOkUserNum() == 0 ? 0 : (float)(erajr.getUserNum() * 1.0 / erajr.getOkUserNum()));

                result.add(erajr);
            }
        }

        return result;
    }

    public class ActivityUserJoinRateData {
        private String platformId;
        private String channelId;
        private String serverId;
        private String platformName;
        private String channelName;
        private String serverName;
        @ChartFlow(name="日期")
        private String day;
        private String activitytype;
        private String activityTypeStr;
        private String activityid;
        private String activityName;
        private int userNum;
        private int joinNum;
        private float joinProUserNum;
        private int okUserNum;
        @ChartSelect(name = "活动参与率", key = 1)
        @ChartData1(name = "活动参与率", key = 1, multiByFiled = "activityName")
        private float userJoinRate;

        public String getPlatformId() {
            return platformId;
        }
        public void setPlatformId(String platformId) {
            this.platformId = platformId;
            this.platformName = BiPlatformManager.getPlatformNameById(platformId);
        }
        public String getChannelId() {
            return channelId;
        }
        public void setChannelId(String channelId) {
            this.channelId = channelId;
            this.channelName =  BiPlatformManager.getChannelNameById(channelId);
        }
        public String getServerId() {
            return serverId;
        }
        public void setServerId(String serverId) {
            this.serverId = serverId;
            this.serverName =  BiPlatformManager.getServerNameById(serverId);
        }
        public String getDay() {
            return day;
        }
        public void setDay(String day) {
            this.day = day;
        }

        public String getPlatformName() {
            return platformName;
        }

        public void setPlatformName(String platformName) {
            this.platformName = platformName;
        }

        public String getChannelName() {
            return channelName;
        }

        public void setChannelName(String channelName) {
            this.channelName = channelName;
        }

        public String getServerName() {
            return serverName;
        }

        public void setServerName(String serverName) {
            this.serverName = serverName;
        }

        public String getActivityTypeStr() {
            return activityTypeStr;
        }

        public void setActivityTypeStr(String activityTypeStr) {
            this.activityTypeStr = activityTypeStr;
        }

        public String getActivityName() {
            return activityName;
        }

        public void setActivityName(String activityName) {
            this.activityName = activityName;
        }

        public int getUserNum() {
            return userNum;
        }

        public void setUserNum(int userNum) {
            this.userNum = userNum;
        }

        public int getJoinNum() {
            return joinNum;
        }

        public void setJoinNum(int joinNum) {
            this.joinNum = joinNum;
        }

        public float getJoinProUserNum() {
            return joinProUserNum;
        }

        public void setJoinProUserNum(float joinProUserNum) {
            this.joinProUserNum = joinProUserNum;
        }

        public int getOkUserNum() {
            return okUserNum;
        }

        public void setOkUserNum(int okUserNum) {
            this.okUserNum = okUserNum;
        }

        public float getUserJoinRate() {
            return userJoinRate;
        }

        public void setUserJoinRate(float userJoinRate) {
            this.userJoinRate = userJoinRate;
        }

        public String getActivitytype() {
            return activitytype;
        }

        public void setActivitytype(String activitytype) {
            this.activitytype = activitytype;
            this.activityTypeStr = GameParamConfigManager.getItemsRevise(CommonGameParam.ACTIVITY_TYPE_NAME).get(activitytype) == null ? activitytype : GameParamConfigManager.getItemsRevise(CommonGameParam.ACTIVITY_TYPE_NAME).get(activitytype);

        }

        public String getActivityid() {
            return activityid;
        }

        public void setActivityid(String activityid) {
            this.activityid = activityid;
            this.activityName = GameParamConfigManager.getItemsRevise(CommonGameParam.ACTIVITY_NAME).get(activityid) == null ? activityid : GameParamConfigManager.getItemsRevise(CommonGameParam.ACTIVITY_NAME).get(activityid);

        }
    }

    public List<ActivityUserJoinNumData> getRoleAcitvityJoinNumDatas(Date dateStart, Date dateEnd, String queryPlatform, String queryChannel, String queryServer, List<Integer> queryVipLevels, String activityType, List<String> activities) {
        if (activities == null || activities.size() <= 0) {
            return null;
        }

        List<ActivityUserJoinNumData> result = new ArrayList<>();

        List<EntityRoleActivityJoinNum> ll = null;
        if (queryVipLevels == null || queryVipLevels.size() <= 0) {
            ll = roleActivityJoinNumManager.getDatas(dateStart, dateEnd, queryPlatform, queryChannel, queryServer, activityType, activities);
        } else {
            ll = roleActivityJoinNumManager.getDatasByVipLevel(dateStart, dateEnd, queryPlatform, queryChannel, queryServer, activityType, activities, queryVipLevels);
        }

        if (ll != null && ll.size() > 0) {
            Map<String, ActivityUserJoinNumData> tmp = new LinkedHashMap<>();
            for (EntityRoleActivityJoinNum e : ll) {
                String key = Time.getDateStr(e.getDay()) + "-" + e.getActivitytype() + "-" + e.getActivityid();

                ActivityUserJoinNumData erajn = tmp.get(key);
                if (erajn == null) {
                    erajn = new ActivityUserJoinNumData();

                    erajn.setDay(Time.getDateStr(e.getDay()));
                    erajn.setPlatformId(e.getPlatformid());
                    erajn.setChannelId(e.getChannelid());
                    erajn.setServerId(e.getServerid());
                    erajn.setActivitytype(e.getActivitytype());
                    erajn.setActivityid(e.getActivityid());

                    tmp.put(key, erajn);
                }

                erajn.setRolenum(erajn.getRolenum() + e.getRolenum());
                erajn.setTimes(erajn.getTimes() + e.getTimes());
            }

            for (Map.Entry<String, ActivityUserJoinNumData> entry : tmp.entrySet()) {
                ActivityUserJoinNumData erajn = entry.getValue();
                erajn.setRoletimes(erajn.getRolenum() == 0 ? 0 : PageHelper.floatKeepOneNumber(erajn.getTimes() * 1.0 / erajn.getRolenum()));

                result.add(erajn);
            }
        }

        return result;
    }

    public class ActivityUserJoinNumData {
        private String platformId;
        private String channelId;
        private String serverId;
        private String platformName;
        private String channelName;
        private String serverName;
        @ChartFlow(name="日期")
        private String day;
        private String activitytype;
        private String activityTypeStr;
        private String activityid;
        private String activityName;
        @ChartSelect(name = "人均参与次数", key = 1)
        @ChartData1(name = "人均参与次数", key = 1, multiByFiled = "activityName")
        private float roletimes;
        private int times;
        private int rolenum;

        public String getPlatformId() {
            return platformId;
        }
        public void setPlatformId(String platformId) {
            this.platformId = platformId;
            this.platformName = BiPlatformManager.getPlatformNameById(platformId);
        }
        public String getChannelId() {
            return channelId;
        }
        public void setChannelId(String channelId) {
            this.channelId = channelId;
            this.channelName =  BiPlatformManager.getChannelNameById(channelId);
        }
        public String getServerId() {
            return serverId;
        }
        public void setServerId(String serverId) {
            this.serverId = serverId;
            this.serverName =  BiPlatformManager.getServerNameById(serverId);
        }
        public String getDay() {
            return day;
        }
        public void setDay(String day) {
            this.day = day;
        }

        public String getPlatformName() {
            return platformName;
        }

        public void setPlatformName(String platformName) {
            this.platformName = platformName;
        }

        public String getChannelName() {
            return channelName;
        }

        public void setChannelName(String channelName) {
            this.channelName = channelName;
        }

        public String getServerName() {
            return serverName;
        }

        public void setServerName(String serverName) {
            this.serverName = serverName;
        }

        public String getActivityTypeStr() {
            return activityTypeStr;
        }

        public void setActivityTypeStr(String activityTypeStr) {
            this.activityTypeStr = activityTypeStr;
        }

        public String getActivityName() {
            return activityName;
        }

        public void setActivityName(String activityName) {
            this.activityName = activityName;
        }

        public float getRoletimes() {
            return roletimes;
        }

        public void setRoletimes(float roletimes) {
            this.roletimes = roletimes;
        }

        public int getTimes() {
            return times;
        }

        public void setTimes(int times) {
            this.times = times;
        }

        public int getRolenum() {
            return rolenum;
        }

        public void setRolenum(int rolenum) {
            this.rolenum = rolenum;
        }

        public String getActivitytype() {
            return activitytype;
        }

        public void setActivitytype(String activitytype) {
            this.activitytype = activitytype;
            this.activityTypeStr = GameParamConfigManager.getItemsRevise(CommonGameParam.ACTIVITY_TYPE_NAME).get(activitytype) == null ? activitytype : GameParamConfigManager.getItemsRevise(CommonGameParam.ACTIVITY_TYPE_NAME).get(activitytype);

        }

        public String getActivityid() {
            return activityid;
        }

        public void setActivityid(String activityid) {
            this.activityid = activityid;
            this.activityName = GameParamConfigManager.getItemsRevise(CommonGameParam.ACTIVITY_NAME).get(activityid) == null ? activityid : GameParamConfigManager.getItemsRevise(CommonGameParam.ACTIVITY_NAME).get(activityid);

        }
    }
}
